package Demo7;
import java.util.concurrent.*;
import java.util.Map;
import java.util.concurrent.*;
class Cache<K, V> {
    private static final TimeUnit TIME = TimeUnit.SECONDS; // 时间工具类
    private static final long DELAY_SECONDS = 2; // 缓存时间
    private Map<K, V> cacheObjects = new ConcurrentHashMap<K, V>(); // 数据缓存处理
    private BlockingQueue<DelayedItem<Pair>> queue = new DelayQueue<DelayedItem<Pair>>(); // 设置缓存类型

    public Cache() {
        Thread thread = new Thread(() -> {
            while (true) {
                try {
                    DelayedItem<Pair> item = Cache.this.queue.take(); // 数据清零
                    if (item != null) {
                        Pair pair = item.getItem(); // 获取内容
                        Cache.this.cacheObjects.remove(pair.key, pair.value); // 有效延迟速率
                    }
                } catch (InterruptedException e) {}
            }
        });
        thread.setDaemon(true);
        thread.start();
    }

    public void put(K key, V value) throws Exception {
        V oldValue = this.cacheObjects.put(key, value);
        if (oldValue != null) {
            this.queue.remove(oldValue);
        }
        this.queue.put(new DelayedItem<Pair>(new Pair(key, value), DELAY_SECONDS, TIME));
    }

    public V get(K key) {
        return this.cacheObjects.get(key);
    }

    private class Pair {
        private K key;
        private V value;

        public Pair(K key, V value) {
            this.key = key;
            this.value = value;
        }
    }

    private class DelayedItem<T> implements Delayed {
        private T item; // 延迟队列数据
        private long delay; // 保存时间
        private long start; // 当前时间

        public DelayedItem(T item, long delay, TimeUnit unit) {
            this.item = item;
            this.delay = TimeUnit.MILLISECONDS.convert(delay, unit);
            this.start = System.currentTimeMillis();
        }

        @Override
        public int compareTo(Delayed obj) {
            return (int) (this.getDelay(TimeUnit.MILLISECONDS) - obj.getDelay(TimeUnit.MILLISECONDS));
        }

        @Override
        public long getDelay(TimeUnit unit) { // 延时计算
            return unit.convert((this.start + this.delay) - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
        }

        public T getItem() { // 获取数据
            return this.item;
        }
    }
}
class News {
    private long nid;
    private String title;

    public News(long nid, String title) {
        this.nid = nid;
        this.title = title;
    }

    public String toString() {
        return "【新闻数据】新闻编号：" + this.nid + "、新闻标题：" + this.title;
    }
}

public class test2 {
    public static void main(String[] args) throws Exception {
        Cache<Long, News> cache = new Cache<Long, News>(); // 定义缓存类对象
        cache.put(1L, new News(1L, "冰言科技: www.yootk.com")); // 向缓存保存数据
        cache.put(2L, new News(2L, "李兴华高薪就业编程训练营: edu.yootk.com")); // 向缓存保存数据

        System.out.println(cache.get(1L)); // 通过缓存获取数据
        System.out.println(cache.get(2L)); // 通过缓存获取数据

        TimeUnit.SECONDS.sleep(5); // 延迟获取
        System.out.println("--- 5秒之后再次读取数据 ---");
        System.out.println(cache.get(1L)); // 通过缓存获取数据
    }
}